package study.sharding.shardingjdbc.support.sharding;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.setting.SettingUtil;
import com.google.common.collect.Range;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.util.Collection;
import java.util.LinkedHashSet;

/**
 * 范围分片算法
 * （1）只支持 BETWEEN AND, >, <, >=, <= 操作
 */
@Slf4j
public class CustomRangeAlgorithm implements RangeShardingAlgorithm<Long> {

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames,
                                         RangeShardingValue<Long> shardingValue) {
        //目标名称
        log.info(">>>>>> available_target_names= [{}]", StrUtil.join(",", availableTargetNames));
        //分片信息：分片表、分片列、分片范围
        String logicTableName = shardingValue.getLogicTableName();
        String columnName = shardingValue.getColumnName();
        Range<Long> range = shardingValue.getValueRange();

        Long lower = range.lowerEndpoint();
        Long upper = range.upperEndpoint();
        log.info(">>>>>> logic_table= [{}], column_name= [{}], range= [{}, {}]", logicTableName, columnName, lower, upper);

        int size = availableTargetNames.size();
        Collection<String> targetLt = CollectionUtil.newLinkedHashSet();
        for (int value = lower.intValue(); value <= upper; value++) {
            for (String targetName : availableTargetNames) {
                //Step-1: 取模
                int mod = value % size;
                //Step-2: 匹配目标
                if (StrUtil.endWith(targetName, NumberUtil.toStr(mod))) {
                    targetLt.add(targetName);
                }
            }
        }
        if (CollectionUtil.isEmpty(targetLt)) {
            throw new UnsupportedOperationException();
        }
        return targetLt;
    }
}
